package top.dyzmj.detty.core.utils.concurrent.executor;

import top.dyzmj.detty.core.utils.concurrent.future.Future;

import java.util.Iterator;
import java.util.concurrent.Callable;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

/**
 * 描述:  事件执行器组
 * {@link EventExecutorGroup} 负责通过它的 {@link #next()} 方法提供 {@link EventExecutor} 的使用。
 * 除此之外，它还负责处理它们的生命周期，并允许在全局范围内关闭它们。
 *
 * @author dongYu
 * @date 2021/11/26
 */
public interface EventExecutorGroup extends ScheduledExecutorService, Iterable<EventExecutor> {

	/**
	 * 当且仅当由该 {@link EventExecutorGroup} 管理的所有 {@link EventExecutor} 被正常关闭或被关闭时返回true。
	 */
	boolean isShuttingDown();

	/**
	 * 用合理的默认值 进行 {@link #shutdownGracefully(long, long, TimeUnit)} 的快捷方法
	 */
	Future<?> shutdownGracefully();

	/**
	 * 向执行器发出信号，表明调用者希望关闭执行器。
	 * 一旦这个方法被调用，{@link #isShuttingDown()} 开始返回true，并且执行器准备关闭自己。
	 * 与shutdown()不同，{@link #shutdownGracefully}确保在关闭之前的“静默期”(通常是几秒钟)没有提交任何任务。
	 * 如果在静默期提交任务，则保证该任务被接受，静默期将重新开始。
	 *
	 * @param quietPeriod 文档中描述的静默期 超时-等待执行器关闭()的最大时间，无论任务是否在静默期间提交
	 * @param timeout     超时时间
	 * @param unit        quietPeriod和timeout的单位
	 * @return {@link #terminationFuture()}
	 */
	Future<?> shutdownGracefully(long quietPeriod, long timeout, TimeUnit unit);

	/**
	 * 返回Future，当由该 {@link EventExecutorGroup} 管理的所有 {@link EventExecutor} 被终止时，该Future将被通知。
	 */
	Future<?> terminationFuture();

	/**
	 * 返回由这个 {@link EventExecutorGroup} 管理的 {@link EventExecutor} 之一。
	 */
	EventExecutor next();

	@Override
	Iterator<EventExecutor> iterator();

	@Override
	Future<?> submit(Runnable task);

	@Override
	<T> Future<T> submit(Runnable task, T result);

	@Override
	<T> Future<T> submit(Callable<T> task);

	@Override
	ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit);

	@Override
	<V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit);

	@Override
	ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);

	@Override
	ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);

}
